<?php
    /******************************************************************************
     *    Copyright Quinn Xu
     * Author:                Quinn Xu
     * Description:           
     * Want argument:         
     * Output:                
     * Create Date:           2012-11-27
     *****************************************************************************/
	class Database
	{
	    private $db_host;//数据库服务器
	    private $db_user;//数据库用户名
	    private $db_pwd;//数据库密码
	    private $db_port;//数据库端口
	    private $db_db;//数据库
	    private $charset;//字符编码
	    private $connect;//数据库连接资源句柄
	    private $stmt;//
	    private $stmtParam;//预处理绑定的参数名数组
	    private $stmtResultFields;//预处理查询的字段名数组

	    /**
	     * @param unknown_type $db_host
	     * @param unknown_type $db_user
	     * @param unknown_type $db_pwd
	     * @param unknown_type $db_port
	     * @param unknown_type $db_db
	     * @param unknown_type $charset
	     */
	    public function __construct($db_host,$db_user,$db_pwd,$db_port,$db_db,$charset='utf8')
	    {
	        $this->db_host = $db_host;
	        $this->db_user = $db_user;
	        $this->db_pwd = $db_pwd;
	        $this->db_db = $db_port;
	        $this->db_port = $db_db;
	        $this->charset = $charset;
	        $this->init();
	    }
	    
	    //连接数据库,设置编码
	    public function init()
	    {
	        $this->connect = new mysqli($this->db_host,$this->db_user,$this->db_pwd,$this->db_port,$this->db_db);
	        $this->connect->set_charset($this->charset);
	    }
	    
	    /**
	     * select语句
	     * @param string $query
	     * @param const $result_type 默认返回文本下表结果集,可以使用的有MYSQLI_BOTH MYSQLI_NUM MYSQLI_ASSOC
	     * @return array 结果集
	     */
	    public function query($query,$result_type=MYSQLI_ASSOC)
	    {
	        $rows = array();
	        $result = $this->connect->query($query);
	        while($row = $result->fetch_array($result_type))
	        {
	            $rows[] = $row;
	        }
	        return $rows;
	    }
	    
	    /**
	     * 执行SQL写操作
	     * @param string $query
	     */
	    public function execute($query)
	    {
	        $result = $this->connect->query($query);
	    }
	    
	    /**
	     * 发送预处理语句,绑定参数变量
	     * @param string $query
	     * @param array $params 第一个元素是绑定参数的类型,后面的是每个参数的名称,不带$
	     * SQLI statement 对象
	     */
	    public function prepare($query,$params)
	    {
	        $this->stmt = $this->connect->prepare($query);
			$this->fileds = null;
			$result_metadata = $this->stmt->result_metadata();
			$fileds_result = $result_metadata->fetch_fields();//获取结果字段信息
			foreach($fileds_result as $value)
			{
			    $this->stmtResultFields[] = $value->name;//获取结果字段名
			}
			unset($result_metadata);
			unset($fileds_result);
	        $param = '';
	        static $index = 0;
	        foreach($params as $value)
	        {
				if($index == 0)
				{
				    $type = '\'' . $value . '\'';
				}
				else 
				{
					$param .= ',$this->' . $value;//这里一定要用this,因为赋值不在一个方法里面,局部变量失效
				}
				$index++;
	        }
	        $evalStr = '$this->stmt->bind_param(' . $type . $param . ');';
	        //将参数变量名保存
	        array_shift($params);
	        $this->stmtParam = $params;
			//绑定参数eval语句$this->stmt->bind_param($types, $var1);
			eval($evalStr);
	        //此路不通call_user_func_array('mysqli_stmt_bind_param',$bindParamArray);
	    }
	    
	    /**
	     * 获取mysqli预处理结果集,仅支持查询操作
	     * @param array $paramValue
	     * $paramValue是设定mysqli预处理参数值的数组,形如array('id'=>1,'pwd'=>12345)
	     * 为了简单还是不写文本下标了,变量名有prepare()语句中的数组设置,写成array(1,2,3)样子<form method="post" action="">
			
	     </form>
	     */
	    public function getStmtResult($paramValue)
	    {
	        foreach ($this->stmtParam as $value)
	        {
	            foreach ($paramValue as $key=>$param)
	            {
	                $this->$value = $param;
	                unset($paramValue[$key]);
	                break;
	            }
	        }
	        unset($paramValue);
	        unset($value);
	        unset($key);
	        unset($param);
	        $this->stmt->execute();
	        $stmtResultStr = '';
	        foreach($this->stmtResultFields as $value)
	        {
	            $stmtResultStr .= ',$' . $value;
	        }
	        $stmtResultStr = substr($stmtResultStr, 1);
	        $evalStr = '$this->stmt->bind_result(' . $stmtResultStr . ');';//绑定预处理结果集
	        eval($evalStr);
	        //$this->stmt->bind_result($result);
	        $this->stmt->store_result();//存储预处理结果集
	        $count = $this->stmt->num_rows();//结果集行数
	        for($i=0;$i<$count;$i++)
	        {
		        $this->stmt->fetch();
		        foreach($this->stmtResultFields as $value)
		        {
			        $result[$i][$value] = $$value;
		        }
	        }
	        $this->stmt->close();
	        return $result;
	    }
	    
	    //执行预处理语句,PDO的,这个支持不定个数的占位符,sql语句形如:select * from zy_user where id = :id
	    public function pdo_prepare($query)
	    {
	        //如果不是PDO对象,无法使用此种绑定方法,直接返回
	        if(!$this->connect instanceof PDO)
	        {
	            return false;
	        }
	        $this->stmt = $this->connect->prepare($query);
	    }
	    
	    
	    //关闭数据库,销毁数据
	    public function __destruct()
	    {
	        $this->connect->close();
	        unset($this);
	    }


		//影响行数
		public function affected_rows()
		{
			return $this->connect->affected_rows;
		}
	}
?>